<?php
declare(strict_types=1);

namespace Service\StockInfoService;

use App\Model\CommodityModel\Stockinfo;
use Service\AppService\IdService;
use Service\AppService\SystemCacheConfigService;
use Service\BaseService;
use Service\Code\Normal;
use Service\ConsumerService\ConsumerMapping\StockInfoMapping;
use function _HumbugBox61bfe547a037\RingCentral\Psr7\str;

class StockInfoService extends BaseService
{
    /**
     * 需要消费需要用的库存数据
     * @param $dataMap
     * @return array
     */
    public function getOldConsumerStockInfos($dataMap)
    {
        $stockInfos = Stockinfo::instance()->whereIn('SupplierCommodityID', array_keys($dataMap))->get()->toArray();
        //需要将SupplierSkuCode映射到Key
        $oldStockInfos = [];
        foreach ($stockInfos as $s) {
            $oldStockInfos[$dataMap[$s['SupplierCommodityID']]] = $s;
        }
        return $oldStockInfos;
    }

    /**
     * 添加库存信息
     * @param $goodsMapping
     * @param $supplierInfo
     * @return array
     */
    public function insertConsumerStockInfo($goodsMapping, $supplierInfo)
    {
        $goodsBase = $goodsMapping['base'];
        $goodsStocks = $goodsMapping['stock'];
        $saveStocks = [];
        $currentTime = date('Y-m-d H:i:s');
        foreach ($goodsStocks as $goodsStock) {
            $computedData = [
                'specList' => $goodsStock['SpecList'] ?? [],
                'isHaveTaxRate' => $goodsStock['IsHaveTaxRate'] ?? 0,
                'taxRate' => $goodsStock['TaxRate'] ?? 0,
                'freightTemplate' => $supplierInfo['FreightTemplate'],
                'weight' => $goodsMapping['other']['weight'] ?? 0
            ];
            $computedPrices = $this->computeFreightPrice($computedData);
            $saveStocks[] = [
                'ID' => IdService::instance()->getOtherID(),
                'IsDefective' => Stockinfo::DEFAULT_IS_DEFECTIVE,
                'IsDeleted' => 0,
                'CommodityArchivesID' => $goodsBase['CommodityArchivesID'] ?? 0,
                'SupplierCompanyID' => $supplierInfo['SupplierID'],
                'SupplierCommodityID' => $goodsBase['ID'],
                'WarehouseID' => $supplierInfo['WarehouseID'],
                'BatchSpecMaxSinglePrice' => $computedPrices['maxPrice'],
                'BatchSpecMinSinglePrice' => $computedPrices['minPrice'],
                'SpecList' => $computedPrices['specList'],
                'LimitBuyCount' => $goodsStock['LimitBuyCount'] ?? 0,
                'BatchID' => $goodsStock['BatchID'] ?? '',
                'CreateTime' => $currentTime,
                'UpdateTime' => $currentTime,
                'Number' => $goodsStock['Number'],
                'BatchNo' => $goodsStock['BatchNo'],
                'IsHasPrice' => $goodsStock['IsHasPrice'] ?? 0,
                'IsHasPeriodTime' => $goodsStock['IsHasPeriodTime'] ?? 0,
                'CalibrationPeriodTime' => $goodsStock['CalibrationPeriodTime'] ?? ''
            ];
        }
        Stockinfo::instance()->insert($saveStocks);
        return Normal::returnSuccessCode();
    }

    /**
     * 计算运费
     * @param $computedData
     * @return array
     */
    private function computeFreightPrice($computedData): array
    {
        $prices = $nums = [];
        foreach ($computedData['specList'] as &$spec) {
            $price = $spec[StockInfoMapping::instance()->SpecPrice];
            //计算含税价
            if ($computedData['isHaveTaxRate'] == 0 && $computedData['taxRate'] != 0) {
                $price = bcmul($spec[StockInfoMapping::instance()->SpecPrice], bcadd('1', (string)$computedData['TaxRate'], 4), 2);
            };
            //计算包邮价
            $freight = 0;
            $singleFreight = 0;
            if ($spec[StockInfoMapping::instance()->SpecPrice] > 0) {
                $singleFreight = $this->getFreightPrice($computedData['freightTemplate'], $computedData['weight'], 1);
                $freight = $this->getFreightPrice($computedData['freightTemplate'], $computedData['weight'], $spec['SpecificationNum']);
            }
            if (is_numeric($spec[StockInfoMapping::instance()->SpecNum])) {
                //只计算含税价
                $prices[] = bcadd(bcdiv((string)$price, (string)$spec[StockInfoMapping::instance()->SpecNum], 2), (string)$singleFreight, 2);
                $nums[] = $spec[StockInfoMapping::instance()->SpecNum];
            }

            //处理格式
            $spec[StockInfoMapping::instance()->SpecPrice] = !empty($spec[StockInfoMapping::instance()->SpecPrice]) ? bcmul($spec[StockInfoMapping::instance()->SpecPrice], "1", 2) : $spec[StockInfoMapping::instance()->SpecPrice];
            $spec[StockInfoMapping::instance()->SpecFreightPrice] = bcadd($spec[StockInfoMapping::instance()->SpecPrice], $freight, 2);

            unset($spec);
        }
        //取最大值和最小值
        $maxPrice = 0;
        $minPrice = 0;
        $IsHasPrice = 0;
        if ($nums) {
            array_multisort($nums, SORT_ASC, $computedData['specList']);
            $maxPrice = max($prices);
            $minPrice = min($prices);
            $IsHasPrice = 1;
        }
        //去重
        $specListArr = array_values(array_column($computedData['specList'], NULL, 'SpecificationNum'));
        return [
            'maxPrice' => $maxPrice,
            'minPrice' => $minPrice,
            'specList' => json_encode($specListArr, JSON_UNESCAPED_UNICODE),
            'isHasPrice' => $IsHasPrice
        ];

    }

    /**
     * 获取运费
     * @param $freightTemplate
     * @param $weight
     * @param $num
     * @return int|string
     */
    private function getFreightPrice($freightTemplate, $weight, $num)
    {
        if (empty($freightTemplate)) {
            return 0;
        }
        if (!isset($freightTemplate['FirstWeightPrice']) || !isset($freightTemplate['AdditionalWeightPrice'])) {
            return 0;
        }
        if (!is_numeric($num)) {
            $num = 1;
        }
        $first_freight = SystemCacheConfigService::instance()->getCacheInfoBySystemCode('first_freight');
        $weight_kg = bcdiv($weight, "1000", 4);
        $weight_kg = bcmul($num, $weight_kg, 4);
        if ($weight_kg < $first_freight) {
            return $freightTemplate['FirstWeightPrice'];
        }
        $additional_weight = bcsub($weight_kg, $first_freight, 4);
        $additional_weight = ceil((float)$additional_weight);
        $AdditionalWeightPrice = bcmul($freightTemplate['AdditionalWeightPrice'], (string)$additional_weight, 2);
        return bcadd($freightTemplate['FirstWeightPrice'], $AdditionalWeightPrice, 2);
    }

    /**
     * 修改库存表的主资料Id
     * @param $oldGoodsId
     * @param $commodityArchivesId
     * @return array
     */
    public function changeStockInfoCommodityArchivesID($oldGoodsId, $commodityArchivesId): array
    {
        Stockinfo::instance()->where('SupplierCommodityID', $oldGoodsId)->update([
            'CommodityArchivesID' => $commodityArchivesId,
            'UpdateTime' => date('Y-m-d H:i:s')
        ]);
        return Normal::returnSuccessCode();
    }

    /**
     * 消费队列修改库存
     * @param $pendingItem
     * @param $supplierInfo
     * @return array
     */
    public function updateConsumerStockInfo($pendingItem, $supplierInfo)
    {
        $goodsMapping = $pendingItem['goodsMapping'];
        $oldGoodsMapping = $pendingItem['oldGoodsMapping'];
        $oldStockMap = [];
        if ($oldGoodsMapping['stock']) {
            $oldStockMap = array_column($oldGoodsMapping['stock'], null, StockInfoMapping::instance()->BatchID);
        }
//        $IsExistBatchNo = array_keys($oldStockMap);
        $CommodityArchivesID = $goodsMapping['base']['CommodityArchivesID'] ?? $oldGoodsMapping['base']['CommodityArchivesID'];
        //运费模板
        if ($supplierInfo['IsSettingFreightTemplate']) {
            $freightTemplate = json_decode($supplierInfo['FreightTemplate'], true);
        } else {
            $freightTemplate = json_decode($oldGoodsMapping['base']['FreightTemplate'], true);
        }
        foreach ($goodsMapping['stock'] as $stock) {
            $computedData = [
                'specList' => $stock['SpecList'] ?? [],
                'isHaveTaxRate' => $goodsMapping['base']['IsHaveTaxRate'] ?? 0,
                'taxRate' => $goodsMapping['base']['TaxRate'] ?? 0,
                'freightTemplate' => $freightTemplate,
                'weight' => $goodsMapping['other']['weight'] ?? 0
            ];
            $computePrice = StockInfoService::instance()->computeFreightPrice($computedData);
//            $existBatchNo[] = $stock['BatchNo'];
            if (isset($oldStockMap[$stock['BatchNo']])) {
                $number_sub = bcsub((string)$stock['Number'], (string)$oldStockMap[$stock['BatchNo']]['NumberLock']);
                $number = max($number_sub, 0);
                $updateData = [
                    'LimitBuyCount' => $stock['LimitBuyCount'] ?? 0,
                    'UpdateTime' => date('Y-m-d H:i:s'),
                    'CommodityArchivesID' => $CommodityArchivesID,
                    'Number' => $number,
                ];
//                if ($supplierInfo['CanModifyStock'] == 1) {
//                    $updateData['Number'] = $number;
//                }
                if ($supplierInfo['CanModifyPrice'] == 0){
                    $updateData = array_merge($updateData,[
                        'BatchSpecMaxSinglePrice' => $computePrice['maxPrice'],
                        'BatchSpecMinSinglePrice' => $computePrice['minPrice'],
                        'SpecList' => $computePrice['specList'],
                        'IsHasPrice' => $stock['IsHasPrice']??0,
                    ]);
                }
                if (isset($stock['BatchID'])){
                    $updateData['BatchID']=$stock['BatchID'];
                }
                //存在就修改数据
                Stockinfo::instance()->where('ID', $oldStockMap[$stock['BatchNo']]['ID'])->update($updateData);
            }else{
                $insertData = [
                    'ID' => IdService::instance()->getOtherID(),
                    'IsDefective' => Stockinfo::DEFAULT_IS_DEFECTIVE,
                    'IsDeleted' => 0,
                    'CommodityArchivesID' => $CommodityArchivesID,
                    'SupplierCompanyID' => $oldGoodsMapping['base']['SupplierCompanyID'],
                    'SupplierCommodityID' => $oldGoodsMapping['base']['ID'],
                    'WarehouseID' => $supplierInfo['WarehouseID'],
                    'BatchSpecMaxSinglePrice' => $computePrice['maxPrice'],
                    'BatchSpecMinSinglePrice' => $computePrice['minPrice'],
                    'SpecList' => $computePrice['specList'],
                    'LimitBuyCount' => $stock['LimitBuyCount'] ?? 0,
                    'BatchID' => $stock['BatchID'] ?? '',
                    'CreateTime' => date('Y-m-d H:i:s'),
                    'Number' => $stock['Number'],
                    'BatchNo' => $stock['BatchNo'],
                    'IsHasPrice' => $stock['IsHasPrice']??0,
                    'IsHasPeriodTime'=>$stock['IsHasPeriodTime']??0,
                    'CalibrationPeriodTime'=>$stock['CalibrationPeriodTime']??''
                ];
                Stockinfo::instance()->insert($insertData);
            }
        }
        //这里考虑删除多余的批次
        //比对存在的数据
        if (!empty($$goodsMapping['isDownBatchNo'])){
            //删除要删除的批次号
            Stockinfo::instance()->whereIn('BatchNo', $goodsMapping['isDownBatchNo'])
                ->where('SupplierCommodityID', $oldGoodsMapping['base']['ID'])
                ->where('SupplierCompanyID', $oldGoodsMapping['base']['SupplierCompanyID'])
                ->delete();
        }

        return Normal::returnCode(Normal::SUC, '库存处理成功');
    }


    /**
     * 消费队列修改库存
     * @param $pendingItem
     * @param $supplierInfo
     * @return array
     */
    public function updateConsumerStockInfoPrice($pendingItem, $supplierInfo)
    {
        $goodsMapping = $pendingItem['goodsMapping'];
        $oldGoodsMapping = $pendingItem['oldGoodsMapping'];

        if ($supplierInfo['IsSettingFreightTemplate']){
            $freightTemplate=json_decode($supplierInfo['FreightTemplate'],true);
        }else{
            $freightTemplate=json_decode($oldGoodsMapping['base']['FreightTemplate'],true);
        }
        foreach ($oldGoodsMapping['stock'] as $stock){
            $spec_list=json_decode($stock['SpecList'],true);
            if (!empty($spec_list)){
                $computedData = [
                    'specList' => $stock['SpecList'] ?? [],
                    'isHaveTaxRate' => $goodsMapping['base']['IsHaveTaxRate'] ?? 0,
                    'taxRate' => $goodsMapping['base']['TaxRate'] ?? 0,
                    'freightTemplate' => $freightTemplate,
                    'weight' => $goodsMapping['other']['weight'] ?? 0
                ];
                $computePrice=StockInfoService::instance()->computeFreightPrice($computedData);
                Stockinfo::instance()->where('ID',$stock['ID'])->update([
                    'BatchSpecMaxSinglePrice' => $computePrice['maxPrice'],
                    'BatchSpecMinSinglePrice' => $computePrice['minPrice'],
                    'SpecList' => $computePrice['specList'],
                    'UpdateTime'=>date('Y-m-d H:i:s')
                ]);
            }
        }
        return Normal::returnCode(Normal::SUC, '库存处理成功');

    }


}